package io.github.elkan1788.tempmonitor;

import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.entity.Record;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.sql.Criteria;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Temperature monitor sample module
 * @author 凡梦星尘(elkan1788@gmail.com)
 */
@IocBean
@At("/temp-monitor")
public class TemperatureMonitorModule {

    private static final Log log = Logs.get();

    private static final SimpleDateFormat DB_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat CHART_DATE_FORMAT = new SimpleDateFormat("MM/dd");
    private static final DecimalFormat TEMP_NUM_FORMAT = new DecimalFormat("#.##");

    @Inject
    private NutDao nutDao;

    public static String TABLE_NAME = "temperature_monitor";

    @At
    @POST
    public Map<String, Object> addTempData(@Param("..")NutMap values) {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("msg", "Success");

        try {
            String option = values.getString("option");
            if ("add".equals(option)) {
                // Check is exist the temperature
                Criteria cri = Cnd.cri();
                cri.where().and("measure_date", "=", values.getString("measure_date"));
                List<Record> exists = nutDao.query(TABLE_NAME, cri, null);
                if (exists != null && !exists.isEmpty()) {
                    result.put("code", 201);
                    result.put("msg", "Duplicate temperature.");
                    result.put("tmpId", exists.get(0).getInt("temp_id"));
                } else {
                    // Add new temperature
                    Chain ch = Chain.make("measure_date", values.getString("measure_date"));
                    ch.add("temperature", TEMP_NUM_FORMAT.format(values.getDouble("temperature")));
                    ch.add("create_time", new Date());
                    nutDao.insert(TABLE_NAME, ch);
                }
            } else if ("update".equals(option)){
                Chain ch = Chain.make("temperature", TEMP_NUM_FORMAT.format(values.getDouble("temperature")));
                ch.add("create_time", new Date());
                int rows = nutDao.update(TABLE_NAME, ch, Cnd.where("temp_id", "=", values.getInt("temp_id")));
                if (rows < 0) {
                    result.put("code", 500);
                    result.put("msg", "Update exist temperature failure!!!");
                }
            }
        } catch (Exception e) {
            log.error("Add new temperature data failure!!!", e);
            result.put("code", 500);
            result.put("msg", "System Error!!!");

        }

        return result;
    }

    @At
    @POST
    public Object getTempData(@Param("type") String type) {
        if (Strings.isBlank(type)) {
            return "参数[type]不能为空值!!!";
        }

        List<Record>  data = nutDao.query(TABLE_NAME, Cnd.orderBy().asc("measure_date"));

        // use EChart
        if (Strings.equalsIgnoreCase("chart", type)) {
            Map<String, Object> tempData = new HashMap<>();
            List<Number> temps = new ArrayList<>();
            List<String> dates = new ArrayList<>();
            data.forEach(r -> {
                try {
                    Date tmp = DB_DATE_FORMAT.parse(r.getString("measure_date"));
                    dates.add(CHART_DATE_FORMAT.format(tmp));
                } catch (ParseException e) {
                    log.error("Format DB date type failure!!!", e);
                }

                try {
                    temps.add(TEMP_NUM_FORMAT.parse(r.getString("temperature")));
                } catch (ParseException e) {
                    log.error("Format DB temp type failure!!!", e);
                }
            });

            tempData.put("temp", temps);
            tempData.put("date", dates);
            log.info(tempData);

            return tempData;
        }

        // use table
        if (Strings.equalsIgnoreCase("table", type)) {
            return data;
        }

        return "未知类型参数!!!";
    }
}
